/* Kanvas Paint and Drawing Tool.
 * Copyright (C) 2011 Darryl Wallace
 * wallacdj@gmail.com / darryl@wallynet.ca
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/*!
  @file Canvas.h
  @author Darryl Wallace
  @date 2011
  @brief This file defines the Canvas.  The canvas is a QGraphicsScene subclass.
  */

#ifndef CANVAS_H
#define CANVAS_H

#include "LibKanvas_global.h"
#include <QtCore>
#include <QtGui>

class LayerItem;
class ITool;

class LIBKANVAS_EXPORT Canvas : public QGraphicsScene
{
    Q_OBJECT
public:
    enum FileSaveTypes{
        UNDEFINED=-1,
        BMP,
        JPG,
        PNG,
        TIFF,
        XBM,
        XPM,
        KANVAS
    };

    enum ResizeAnchor{
        TopLeft,
        Top,
        TopRight,
        Left,
        Center,
        Right,
        BottomLeft,
        Bottom,
        BottomRight
    };

    Canvas(int w=800, int h=600, QObject *parent = 0);
    virtual ~Canvas() {};

    /// Returns true if layer was successfully added.  This layer is added on top.
    bool addLayer();
    /// Returns true if layer was successfully deleted.
    bool deleteLayer(int index);
    /// Returns true if layer was successfully set.
    bool setCurrentLayer(int index);
    /// Returns a pointer to the layer at index.  Returns NULL if that index is invalid.
    LayerItem *getLayer(int index);
    /// Returns the current index.
    int getCurrentLayerIndex() const ;

    /// Shifts the layer at index up one.
    void moveLayerUp(int index);
    /// Shifts the layer at index down one.
    void moveLayerDown(int index);

    void setPrimaryColor(const QColor &p);
    void setSecondaryColor(const QColor &s);

    void setCurrentTool(ITool *);

    void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event);

    void mousePressEvent(QGraphicsSceneMouseEvent *event);

    void mouseMoveEvent(QGraphicsSceneMouseEvent *event);

    void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);

    void save(const QString &filename, FileSaveTypes type = UNDEFINED);

    /// Resize the canvas
    /*!
      This will resize the canvas and all of it's layers accordingly.

      For example, resizing the image with the center anchor location would add the difference
      from each side.
      \param width The new width of the layer.
      \param height The new height of the layer.
      \param anchorLocation Resize anchor location.
      */
    void resize(int width, int height, ResizeAnchor anchorLocation=TopLeft);

    /// Scale the canvas
    /*!
      This will resize the canvas and scale all layers accordingly.

      Scaling will use bilinear transformation for smooth transformations.
      \param sx scale value in the x-axis as a multiplication factor.
      \param sy scale value in the y-axis as a multiplication factor.
      */
    void scaleImage(qreal sx, qreal sy);

    void enablePixelGrid(bool on=false);

    void setLayerVisible(int index, bool visible=true);

    QSize canvasSize() const ;

    void applyTransformToTool();

public slots:
    void setCurrentZoomFactor(qreal zoomfactor);

signals:
    /// Emitted with a status message that should be displayed on the status bar.
    void statusMessage(const QString &message);


private:
    QGraphicsRectItem *_backgroundLayer;
    QGraphicsItem *_pixelGrid;
    QList<LayerItem *> _layers;
    LayerItem *_currentLayer;
    int _currentLayerIndex;

    qreal _currentZoomFactor;

    QColor _primaryColor;
    QColor _secondaryColor;

    ITool *_currentTool;
    ITool *_activeTool;
};

#endif // LIBKANVAS_H
